package com.wngbms.netty.book._06endec._02;

import com.wngbms.netty.book._06endec._01.Byte2IntegerDecoder;
import com.wngbms.netty.book._06endec._01.Byte2StringDecoder;
import com.wngbms.netty.book._06endec._01.IntegerProcessHandler;
import com.wngbms.netty.book._06endec._01.StringProcessHandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Random;

@Slf4j
public class NettyOpenBoxDecoder {

    public static void main(String[] args) {
//        lineBasedFrameDecoder();
//        delimiterBasedFrameDecoder();
//        simpleLengthFieldBasedDecoder();

        LengthFieldBasedFrameDecoder spliter = new LengthFieldBasedFrameDecoder(4096, 2, 4, 4, 10);

        ChannelInitializer channelInitializer = new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(spliter);
                pipeline.addLast(new StringDecoder());
                pipeline.addLast(new StringProcessHandler());
            }
        };

        EmbeddedChannel channel = new EmbeddedChannel(channelInitializer);

        String content = "苹果手机真香";

        for (int i = 0; i < 1; i++) {
            ByteBuf buffer = Unpooled.buffer();
            String s = i + "次发送->" + content;
            byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
            buffer.writeChar('A');
            buffer.writeInt(bytes.length);
            buffer.writeInt(999);
            buffer.writeBytes(bytes);
            channel.writeInbound(buffer);
        }
    }

    private static void simpleLengthFieldBasedDecoder() {
        LengthFieldBasedFrameDecoder spliter = new LengthFieldBasedFrameDecoder(4096, 0, 4, 0, 4);

        ChannelInitializer channelInitializer = new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(spliter);
                pipeline.addLast(new StringDecoder());
                pipeline.addLast(new StringProcessHandler());
            }
        };

        EmbeddedChannel channel = new EmbeddedChannel(channelInitializer);

        String content = "苹果手机真香";

        for (int i = 0; i < 100; i++) {
            ByteBuf buffer = Unpooled.buffer();
            String s = i + "次发送->" + content;
            byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
            buffer.writeInt(bytes.length);
            buffer.writeBytes(bytes);
            channel.writeInbound(buffer);
        }
    }

    private static void delimiterBasedFrameDecoder() {
        ChannelInitializer channelInitializer = new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(new DelimiterBasedFrameDecoder(1024, true, Unpooled.copiedBuffer("\t".getBytes(StandardCharsets.UTF_8))));
                pipeline.addLast(new Byte2StringDecoder());
                pipeline.addLast(new StringProcessHandler());
            }
        };

        byte[] bytes = "苹果手机真香".getBytes(StandardCharsets.UTF_8);

        log.info("length:{}", bytes.length);

        EmbeddedChannel channel = new EmbeddedChannel(channelInitializer);

        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int i1 = random.nextInt(4) + 1;

            log.info("======================================= {}", i1);
            for (int i2 = 0; i2 < i1; i2++) {
                ByteBuf buffer = Unpooled.buffer();
                buffer.writeBytes(bytes);
                channel.writeInbound(buffer);
            }
            ByteBuf buffer = Unpooled.buffer();
            buffer.writeBytes("\t".getBytes(StandardCharsets.UTF_8));
            channel.writeInbound(buffer);
        }
    }

    private static void lineBasedFrameDecoder() {
        ChannelInitializer channelInitializer = new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(new LineBasedFrameDecoder(54));
                pipeline.addLast(new Byte2StringDecoder());
                pipeline.addLast(new StringProcessHandler());
            }
        };

        byte[] bytes = "苹果手机真香".getBytes(StandardCharsets.UTF_8);

        log.info("length:{}", bytes.length);

        EmbeddedChannel channel = new EmbeddedChannel(channelInitializer);

        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int i1 = random.nextInt(4) + 1;

            log.info("======================================= {}", i1);
            for (int i2 = 0; i2 < i1; i2++) {
                ByteBuf buffer = Unpooled.buffer();
                buffer.writeBytes(bytes);
                channel.writeInbound(buffer);
            }
            ByteBuf buffer = Unpooled.buffer();
            buffer.writeBytes("\r\n".getBytes(StandardCharsets.UTF_8));
            channel.writeInbound(buffer);
        }
    }

}
